#pragma once 

#include "graphics/Shader.h"

class Rect2D
{
public:
    Rect2D()
    {
        shader = getSimple2DShader();
        initGeom();
    }
    void initGeom()
    {
        PC2DVertex vertices[4];
        unsigned int i = 0;

        glGenBuffers(1, &vbo);
        glGenVertexArrays(1, &vao);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        {
            glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(PC2DVertex), nullptr, GL_DYNAMIC_DRAW);
        } glBindBuffer(GL_ARRAY_BUFFER, 0);

        glBindVertexArray(vao);
        {
            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            {
                unsigned int offset = 0;
                glVertexAttribPointer(semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(PC2DVertex), BUFFER_OFFSET(offset));
                offset += sizeof(glm::vec2);
                glVertexAttribPointer(semantic::attr::COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(PC2DVertex), BUFFER_OFFSET(offset));
            } 
            glEnableVertexAttribArray(semantic::attr::POSITION);
            glEnableVertexAttribArray(semantic::attr::COLOR);
        } glBindVertexArray(0);
    }
    void updateGeom(const glm::dvec4& rect)
    {
        PC2DVertex vertices[4];
        unsigned int i = 0;
     
		vertices[i++] = PC2DVertex(glm::vec2(rect[0], rect[1]), glm::vec4(1.0, 1.0, 0.0, 1.0));
        vertices[i++] = PC2DVertex(glm::vec2(rect[2], rect[1]), glm::vec4(1.0, 1.0, 0.0, 1.0));
        vertices[i++] = PC2DVertex(glm::vec2(rect[2], rect[3]), glm::vec4(1.0, 1.0, 0.0, 1.0));
        vertices[i++] = PC2DVertex(glm::vec2(rect[0], rect[3]), glm::vec4(1.0, 1.0, 0.0, 1.0));

        glBindVertexArray(vao);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        {
            glBufferSubData(GL_ARRAY_BUFFER, 0, 4 * sizeof(PC2DVertex), &vertices[0]);
        } glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        flushGLError("Rect2D.updateGeom()"); 
    }
    void draw()
    {
        shader->begin();
        {
            int projLoc = shader->getUniLoc("proj");
            int colorLoc = shader->getUniLoc("renColor"); 

            glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(Game::getOrthoMatrix()));
            glUniform4f(colorLoc, 1.0f, 1.0f, 0.0f, 1.0f);

			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            glDisable(GL_DEPTH_TEST);
            glDisable(GL_CULL_FACE);
            glBindVertexArray(vao);
            {
                glDrawArrays(GL_QUADS, 0, 4);
            } glBindVertexArray(0);
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
			glEnable(GL_DEPTH_TEST);
			glEnable(GL_CULL_FACE);
        } shader->end();
       flushGLError("Rect2D.draw()"); 
    }

private:
    GLuint vao;
    GLuint vbo;
    Shader* shader;
};